<script lang="ts" setup>
import { computed, ref } from 'vue';

import { Page } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { getPopupContainer } from '@vben/utils';

import { CopyOutlined } from '@ant-design/icons-vue';
import { useClipboard } from '@vueuse/core';
// import { renderDict } from '#/utils/render';
import { Card, message, Result, Space, Step, Steps } from 'ant-design-vue';
import dayjs from 'dayjs';

import { useVbenForm } from '#/adapter/form';
import { dictDataInfo } from '#/api/system/dict/dict-data';
import { getDictOptions } from '#/utils/dict';
import { downloadImage } from '#/utils/file/download';
import { getMiniProQrcode } from '#/utils/wechat';

const currentTab = ref(0);
const appIdOption = ref<any>(null);
const pathOption = ref<any>(null);
const qrcodeImgUrl = ref<string>('');
const resultTitle = computed(() => {
  return appIdOption.value ? `${appIdOption.value.label}` : '小程序码';
});
const fullPath = ref<string>('');

const [Form, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
  },
  handleSubmit: onSubmit,
  layout: 'horizontal',
  resetButtonOptions: {
    show: false,
  },
  schema: [
    {
      component: 'Select',
      componentProps: {
        getPopupContainer,
        labelInValue: true,
        placeholder: '请选择小程序',
        options: getDictOptions(DictEnum.WECHAT_MINIPROGRAM_LIST),
        onSelect: (value: any) => {
          handleAppIdChange(value);
        },
      },
      fieldName: 'appId',
      label: '关联小程序',
      rules: 'required',
    },
    {
      component: 'Select',
      componentProps: {
        getPopupContainer,
        labelInValue: true,
        placeholder: '请选择页面路径',
        notFoundContent: '请先选择关联的小程序',
        options: [],
        onSelect: (value: any) => {
          handlePathChange(value);
          fullPathPreview();
        },
      },
      fieldName: 'path',
      label: '小程序页面',
      rules: 'required',
    },
    {
      component: 'Input',
      componentProps: {
        placeholder: '示例：id=123&sourceName=test&key1=value1&key2=value2',
        options: [],
        onInput: () => {
          fullPathPreview();
        },
      },
      fieldName: 'query',
      label: '路径参数',
      help: '参数中不需要带问号，多个参数之间用&拼接，完整格式如下：\nid=1&name=sugar',
    },
    {
      component: 'Input',
      fieldName: 'pathPreview',
      label: '完整路径',
      componentProps: {
        disabled: true,
      },
      help: '展示完整路径，包含所选页面地址+填写的参数',
    },
  ],
  submitButtonOptions: {
    content: '生成小程序码',
  },
  wrapperClass: 'grid-cols-1 md:grid-cols-1 lg:grid-cols-1',
});

async function handleAppIdChange(option: any) {
  const list = (await dictDataInfo(option.value)) ?? [];
  await formApi.setFieldValue('path', undefined);
  await formApi.setFieldValue('query', undefined);
  fullPath.value = '';
  appIdOption.value = option;
  formApi.updateSchema([
    {
      fieldName: 'path',
      componentProps: {
        options: list.map((item) => {
          return {
            label: `${item.dictLabel} ${item.dictValue}`,
            value: item.dictValue,
            title: item.dictLabel,
          };
        }),
      },
    },
  ]);
}

function handlePathChange(option: any) {
  pathOption.value = option;
}

async function fullPathPreview() {
  const data = await formApi.getValues();
  const path = data.path.value;
  const query = data.query || '';
  let fullQuery = '';
  if (query) {
    fullQuery = path.includes('?') ? `&${query}` : `?${query}`;
  }
  fullPath.value = `${path}${fullQuery}`;
  // await formApi.setFieldValue('pathPreview', `${path}?${query}`);
}

async function onSubmit(values: Record<string, any>) {
  console.log(values);
  formApi.setState({
    submitButtonOptions: { loading: true },
  });

  let path = values.path.value;
  if (values.query) {
    const prefix = path.includes('?') ? '' : '?';
    path += `${prefix}${values.query.replaceAll('?', '')}`;
  }
  appIdOption.value = values.appId;
  pathOption.value = values.path;
  const imgUrl = await getMiniProQrcode(values.appId.value, path);
  if (imgUrl) {
    qrcodeImgUrl.value = imgUrl;
    currentTab.value = 1;
  } else {
    message.error('生成失败');
  }
  formApi.setState({
    submitButtonOptions: { loading: false },
  });
}

async function reset() {
  await formApi.resetForm();
  appIdOption.value = null;
  pathOption.value = null;
  qrcodeImgUrl.value = '';
  currentTab.value = 0;
}

const downloadLoading = ref(false);

async function downloadImg() {
  if (qrcodeImgUrl.value) {
    downloadLoading.value = true;
    await downloadImage(
      qrcodeImgUrl.value,
      `${resultTitle.value}${pathOption.value?.option?.title || ''}_小程序码_${dayjs().format('YYYYMMDDHHmmss')}`,
    );
    downloadLoading.value = false;
  }
}

const { copy } = useClipboard({ legacy: true });

async function handleCopy(text: string) {
  await copy(text);
  message.success('完整路径复制成功');
}
</script>

<template>
  <Page title="生成小程序码">
    <Card>
      <div class="mx-auto w-[800px]">
        <Steps :current="currentTab" class="steps">
          <Step title="填写信息" />
          <Step title="小程序码图片" />
        </Steps>
        <div class="p-[40px]">
          <div class="mx-auto w-[600px]">
            <Form v-show="currentTab === 0">
              <template #pathPreview>
                {{ fullPath }}
                <span v-if="fullPath" class="ml-[8px]">
                  <CopyOutlined
                    class="cursor-pointer"
                    title="复制"
                    @click="handleCopy(fullPath)"
                  />
                </span>
              </template>
            </Form>
          </div>
          <div v-show="currentTab === 1">
            <Result :title="resultTitle">
              <template #icon>
                <img
                  :src="qrcodeImgUrl"
                  alt=""
                  class="mx-auto h-[258px] w-[258px]"
                />
              </template>
              <template v-if="pathOption" #subTitle>
                <div>{{ pathOption?.option?.title }}</div>
                <div>{{ fullPath }}</div>
              </template>
              <template #extra>
                <Space>
                  <a-button @click="reset">重新生成</a-button>
                  <a-button
                    :loading="downloadLoading"
                    type="primary"
                    @click="downloadImg"
                  >
                    下载图片
                  </a-button>
                </Space>
              </template>
            </Result>
          </div>
        </div>
      </div>
    </Card>
  </Page>
</template>
